﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.AspNetCore.DependencyInjection/ServiceCollectionExtensions 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       ServiceCollectionExtensions
* 创建时间：  2025/5/23 17:28:43
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using AspNetCoreRateLimit;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Google.Protobuf.WellKnownTypes;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SSPivot;
using SSPivot.AspNetCore.Abstractions.Data;
using SSPivot.AspNetCore.Config;
using SSPivot.AspNetCore.DependencyInjection;
using SSPivot.AspNetCore.Repository;
using SSPivot.Common.Helpers;
using SSPivot.Data.MultiTenancy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.Formula.Functions;
using Consul;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using SSPivot.AspNetCore.Abstractions.User;
using SSPivot.AspNetCore.Auth;
using SSPivot.Authorization.Authorize;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.IdentityModel.Tokens.Jwt;
using SSPivot.Authorization.User;
using SSPivot.Authorization.Security;
using SSPivot.Common;
using System.Security.Claims;
using SSPivot.AspNetCore;
using Microsoft.EntityFrameworkCore;
using SSPivot.Data.Config;
using SSPivot.Authorization.Config;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class StartupExtensions
    {
        #region Authorization
        public static IServiceCollection AddSSPivotAuthorization<THandler>(this IServiceCollection services,IConfiguration configuration) where THandler : PermissionHandler
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            var config = configuration.GetSection("Auth").Get<AuthConfig>();// ConfigHelper.GetOptions<AuthConfig>("AuthConfig");
            if (config.AuthType == "jwt")
            {
                if (services == null) throw new ArgumentNullException(nameof(services));

                //读取配置
                var jwtConfiguration = config.JwtConfig;

                // 获取密钥
                var keyByteArray = Encoding.UTF8.GetBytes(jwtConfiguration.SecurityKey);
                var signingKey = new SymmetricSecurityKey(keyByteArray);

                // 令牌验证参数
                var tokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true, // 是否验证SecurityKey 
                    ValidateIssuer = true, // 是否验证Issuer 
                    ValidateAudience = true, // 是否验证Audience
                    ValidateLifetime = true, // 是否验证失效时间
                    ClockSkew = TimeSpan.Zero, // 设置时钟偏移为0 
                    IssuerSigningKey = signingKey, //签名验证的密钥
                    ValidIssuer = jwtConfiguration.Issuer, // 发行人Issuer  指定发行者
                    ValidAudience = jwtConfiguration.Audience // 订阅人Audience 指定受众
                };

                // events
                var jwtBearerEvents = new JwtBearerEvents
                {
                    //  1. **OnMessageReceived**:
                    //   -触发时机：当接收到一个身份验证请求。
                    //   -用途：用来处理接收到的原始身份验证消息，你可以根据请求的具体情况来修改或取消身份验证过程。

                    //2. * *OnTokenValidated * *:
                    //   -触发时机：在JWT被成功验证后触发。
                    //   -用途：用来处理已验证的token，例如，你可以在这里添加额外的日志记录或执行一些安全检查。

                    //3. * *OnAuthenticationFailed * *:
                    //   -触发时机：当身份验证失败时触发。
                    //   -用途：用来处理身份验证失败的情况，例如，记录失败原因、执行额外的错误处理逻辑等。

                    //4. * *OnChallenge * *:
                    //   -触发时机：当需要向客户端发出一个挑战（例如，要求客户端提供凭据）时触发。
                    //   -用途：自定义挑战的响应，例如，修改返回给客户端的`401 Unauthorized`响应。

                    //5. * *OnForbidden * *:
                    //   -触发时机：当授权失败时触发（即用户已通过身份验证，但没有足够的权限访问特定资源）。
                    //   -用途：自定义处理禁止访问的情况，例如，返回一个自定义的错误消息或执行其他逻辑。


                    //接受到消息时调用
                    OnMessageReceived = context =>
                    {
                        var token = context.Request.Headers[SSPivot.AspNetCore.GlobalConfigAspNetCore.AuthorizationHeader].ToString()?.Replace("Bearer ", "");
                        if (!string.IsNullOrEmpty(token))
                        {
                            context.Token = token;
                        }
                        return Task.CompletedTask;
                    },
                    //在Token验证通过后调用
                    OnTokenValidated = context =>
                    {
                        var CurrentUser = context.HttpContext.RequestServices.GetService<ICurrentUser>();

                        var claims = context.Principal.Claims;
                        //CurrentUser.Id = claims.First(x => x.Type == LHHTClaimTypes.UserId).Value.ToLong();
                        //CurrentUser.Account = claims.First(x => x.Type == LHHTClaimTypes.Account).Value;
                        //CurrentUser.Name = claims.First(x => x.Type == ClaimTypes.Name).Value;
                        //CurrentUser.Email = claims.First(x => x.Type == LHHTClaimTypes.Email).Value;
                        //CurrentUser.Roles = claims.First(x => x.Type == ClaimTypes.Role).Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
                        //CurrentUser.RoleScope = claims.First(x => x.Type == ClaimTypes.Role).Value;
                        //CurrentUser.Type = (UserType)claims.First(x => x.Type == LHHTClaimTypes.UserType).Value.To<int>();
                        return Task.CompletedTask;
                    },
                    //认证失败时调用
                    OnAuthenticationFailed = context =>
                    {
                        var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
                        var jwtToken = (new JwtSecurityTokenHandler()).ReadJwtToken(token);

                        if (jwtToken.Issuer != jwtConfiguration.Issuer)
                        {
                            context.Response.Headers.Append("Token-Error-Iss", "issuer is wrong!");
                        }

                        if (jwtToken.Audiences.FirstOrDefault() != jwtConfiguration.Audience)
                        {
                            context.Response.Headers.Append("Token-Error-Aud", "Audience is wrong!");
                        }

                        // 如果过期，则把<是否过期>添加到，返回头信息中
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Append("Token-Expired", "true");
                        }
                        return Task.CompletedTask;
                    },
                    //未授权时调用
                    OnChallenge = context =>
                    {
                        context.Response.Headers.Append("Token-Error", context.ErrorDescription);
                        return Task.CompletedTask;
                    },
                    OnForbidden = async context =>
                    {
                        context.Response.StatusCode = (int)SSPivot.StatusCodes.Status403Forbidden;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync("403");
                    }
                };
                //复杂的策略授权
                services.AddAuthorization(options =>
                {
                    options.AddPolicy(SSPivot.AspNetCore.GlobalConfigAspNetCore.AuthorizationPolicy, policy => policy.Requirements.Add(new PermissionRequirement()));
                });

                //添加身份验证-
                services.AddAuthentication(options =>
                {
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = nameof(ResponseAuthenticationHandler); //401
                    options.DefaultForbidScheme = nameof(ResponseAuthenticationHandler);    //403
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(options =>
                {
                    //验证token
                    options.TokenValidationParameters = tokenValidationParameters;
                    options.Events = jwtBearerEvents;
                }).AddScheme<AuthenticationSchemeOptions, ResponseAuthenticationHandler>(nameof(ResponseAuthenticationHandler), o => { });
                services.AddScoped<IAuthorizationHandler, THandler>();
            }
            else
            {
                //AccessToken自定义认证
                services.AddAuthentication(SSPivot.AspNetCore.GlobalConfigAspNetCore.AuthenticationScheme).AddAccessToken();
                services.AddAuthorizationCore(); 
                services.AddSingleton<ICurrentPrincipalAccessor, HttpContextCurrentPrincipalAccessor>(); 
                services.AddAuthorization(options =>
                {
                    options.AddPolicy(SSPivot.AspNetCore.GlobalConfigAspNetCore.AuthorizationPolicy, policy =>
                        policy.Requirements.Add(new PermissionRequirement()));
                });
                services.AddScoped<IAuthorizationHandler, THandler>();
            }
            services.AddScoped<ICurrentUser, CurrentUser>();
            return services;
        }


        /// <summary>
        /// 添加JwtBearer支持
        /// </summary>
        public static AuthenticationBuilder AddJwtBearer(IServiceCollection services, AuthenticationBuilder builder)
        {
            var config =  ConfigHelper.GetOptions<AuthConfig>("AuthConfig");


            builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
                opts =>
                {
                    string secret = config.JwtConfig.SecurityKey;
                    if (secret.IsNullOrEmpty())
                    {
                        throw new SSPivotException("JwtConfig:SecurityKey不能为空");
                    }

                    opts.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidIssuer = config.JwtConfig.Issuer ?? "osharp identity",
                        ValidAudience = config.JwtConfig.Audience ?? "osharp client",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
                        LifetimeValidator = (nbf, exp, token, param) => exp > DateTime.UtcNow
                    };

                    opts.Events = new JwtBearerEvents()
                    {
                        OnAuthenticationFailed = context =>
                        {
                            var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
                            var jwtToken = (new JwtSecurityTokenHandler()).ReadJwtToken(token);

                            if (jwtToken.Issuer != config.JwtConfig.Issuer)
                            {
                                context.Response.Headers.Append("Token-Error-Iss", "issuer is wrong!");
                            }

                            if (jwtToken.Audiences.FirstOrDefault() != config.JwtConfig.Audience)
                            {
                                context.Response.Headers.Append("Token-Error-Aud", "Audience is wrong!");
                            }
                            return Task.CompletedTask;
                        },
                        OnChallenge = context => { context.Response.Headers.Append("Token-Error", context.ErrorDescription); return Task.CompletedTask; },
                        OnForbidden = async context => { context.Response.StatusCode = (int)SSPivot.StatusCodes.Status403Forbidden; context.Response.ContentType = "application/json"; await context.Response.WriteAsync("403"); },
                        OnMessageReceived = context => {
                            string token = context.Request.Query["access_token"];
                            string path = context.HttpContext.Request.Path;
                            if (!string.IsNullOrEmpty(token) && path.Contains("hub"))
                            {
                                context.Token = token;
                            }

                            return Task.CompletedTask;
                           
                        },
                        OnTokenValidated =  context => {

                            ClaimsPrincipal user = context.Principal;
                            ClaimsIdentity identity = user.Identity as ClaimsIdentity;

                            //IUserClaimsProvider accessClaimsProvider = context.HttpContext.RequestServices.GetService<IUserClaimsProvider>();
                            //OperationResult<ClaimsIdentity> result = await accessClaimsProvider.RefreshIdentity(identity);
                            //if (!result.Succeeded)
                            //{
                            //    context.Fail(result.Message);
                            //}
                            return Task.CompletedTask; 
                        },

                    };
                });

            return builder;
        }

        private static AuthenticationBuilder AddCookie(IServiceCollection services, AuthenticationBuilder builder)
        {
            //OsharpOptions options = services.GetOsharpOptions();
            //CookieOptions cookie = options.Cookie;
            //if (cookie?.Enabled != true)
            //{
            //    return builder;
            //}

            //services.AddScoped<OsharpCookieAuthenticationEvents>();
            //builder.AddIdentityCookies(b =>
            //{
            //    b.ApplicationCookie.Configure(opts =>
            //    {
            //        if (cookie.CookieName != null)
            //        {
            //            opts.Cookie.Name = cookie.CookieName;
            //        }

            //        opts.LoginPath = cookie.LoginPath ?? opts.LoginPath;
            //        opts.LogoutPath = cookie.LogoutPath ?? opts.LogoutPath;
            //        opts.AccessDeniedPath = cookie.AccessDeniedPath ?? opts.AccessDeniedPath;
            //        opts.ReturnUrlParameter = cookie.ReturnUrlParameter ?? opts.ReturnUrlParameter;
            //        opts.SlidingExpiration = cookie.SlidingExpiration;
            //        if (cookie.ExpireMins > 0)
            //        {
            //            opts.ExpireTimeSpan = TimeSpan.FromMinutes(cookie.ExpireMins);
            //        }

            //        opts.EventsType = typeof(OsharpCookieAuthenticationEvents);
            //    });
            //});
            return builder;
        }

        /// <summary>
        /// 添加OAuth2第三方登录配置
        /// </summary>
        private static AuthenticationBuilder AddOAuth2(IServiceCollection services, AuthenticationBuilder builder)
        {
            //OsharpOptions osharpOptions = services.GetOsharpOptions();
            //IDictionary<string, OAuth2Options> dict = osharpOptions.OAuth2S;
            //if (dict == null || dict.Count == 0)
            //{
            //    return builder;
            //}

            //foreach (var (name, options) in dict)
            //{
            //    if (!options.Enabled)
            //    {
            //        continue;
            //    }

            //    if (string.IsNullOrEmpty(options.ClientId))
            //    {
            //        throw new OsharpException($"配置文件中OSharp:OAuth2配置的{name}节点的ClientId不能为空");
            //    }

            //    if (string.IsNullOrEmpty(options.ClientSecret))
            //    {
            //        throw new OsharpException($"配置文件中OSharp:OAuth2配置的{name}节点的ClientSecret不能为空");
            //    }

            //    switch (name)
            //    {
            //        case "QQ":
            //            builder.AddQQ(opts =>
            //            {
            //                opts.AppId = options.ClientId;
            //                opts.AppKey = options.ClientSecret;
            //            });
            //            break;
            //        case "Microsoft":
            //            builder.AddMicrosoftAccount(opts =>
            //            {
            //                opts.ClientId = options.ClientId;
            //                opts.ClientSecret = options.ClientSecret;
            //            });
            //            break;
            //            //case "GitHub":
            //            //    builder.AddGitHub(opts =>
            //            //    {
            //            //        opts.ClientId = options.ClientId;
            //            //        opts.ClientSecret = options.ClientSecret;
            //            //    });
            //            //    break;
            //    }
            //}

            return builder;
        }
        #endregion

        #region cros
        public static void AddSSPivotCros(this IServiceCollection services, IConfiguration configuration)
        {
            var config = configuration.GetSection("Cros").Get<CrosConfig>();
            services.AddCors(c =>
            {
                if (!config.CorsEnableAllIPs)
                {
                    c.AddPolicy(config.CorsPolicyName, policy =>
                    {
                        policy.WithOrigins(config.CorsIps.Split(','));
                        policy.AllowAnyHeader();//Ensures that the policy allows any header.
                        policy.AllowAnyMethod();
                        policy.AllowCredentials();
                    });
                }
                else
                {
                    //允许任意跨域请求
                    c.AddPolicy(config.CorsPolicyName, policy =>
                    {
                        policy.SetIsOriginAllowed((host) => true)
                            .AllowAnyMethod()
                            .AllowAnyHeader()
                            .AllowCredentials();
                    });
                }
                c.AddPolicy(SSPivot.AspNetCore.GlobalConfigAspNetCore.AllowAnyPolicyName, policy =>
                {
                    policy
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
        }
        /// <summary>
        /// 启用限流中间件（在路由之后，端点之前）,建议放在app.UseRouting();之后，
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static void UseSSPivotCros(this WebApplication app, IConfiguration configuration)
        {
            var config = configuration.GetSection("Cros").Get<CrosConfig>();
            app.UseCors(config.CorsPolicyName);
        }
        #endregion

        #region ip限流
        /// <summary>
        /// 添加Ip限流
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <param name="cacheConfig"></param>
        public static void AddSSPivotIpRateLimit(this IServiceCollection services, IConfiguration configuration)
        {
            #region IP限流
            var isIpRateLimitEnable = configuration.GetSection("AppSettings").GetValue<bool>("IpRateLimitingEnabled", false);// ConfigHelper.GetAppSettingBoolean("IpRateLimitingEnabled");
            var isIpRateLimitPoliciesEnabled = configuration.GetSection("AppSettings").GetValue<bool>("IpRateLimitPoliciesEnabled", false);// ConfigHelper.GetAppSettingBoolean("IpRateLimitPoliciesEnabled");
            var isUseDistributedEnabled= configuration.GetSection("AppSettings").GetValue<bool>("UseDistributed", false); //ConfigHelper.GetAppSettingBoolean("UseDistributed");
            if (isIpRateLimitEnable)
            {
                // 加载配置
                services.Configure<IpRateLimitOptions>(configuration.GetSection("IpRateLimiting")); 

                if (isIpRateLimitPoliciesEnabled)
                    services.Configure<IpRateLimitPolicies>(configuration.GetSection("IpRateLimitPolicies"));
                if (isUseDistributedEnabled)
                {
                    services.AddDistributedRateLimiting(); 
                }
                else
                {
                    services.AddInMemoryRateLimiting();
                }
                services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); 
            } 
            #endregion IP限流
        }
        /// <summary>
        /// 启用限流中间件（在路由之后，端点之前）,建议放在app.UseRouting();之后，
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseSSPivotIpRateLimiting(this WebApplication app)
        { 
            return app.UseMiddleware<IpRateLimitMiddleware>();
        }
        #endregion

        #region datafilter
        /// <summary>
        /// 添加数据上下文
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddDataFilterSetUp(this IServiceCollection services)
        {
            #region 多租户
            //// 多租户配置
            //builder.Services.AddScoped<TenantContext>();
            //builder.Services.AddScoped<ITenantResolver, ConfigTenantResolver>();

            //// 动态DbContext注册
            //builder.Services.AddScoped<AppDbContext>(sp =>
            //{
            //    var tenantContext = sp.GetRequiredService<TenantContext>();
            //    var config = sp.GetRequiredService<IConfiguration>();
            //    var factory = new TenantDbContextFactory(tenantContext.CurrentTenant, config);
            //    return factory.CreateDbContext();
            //});

            //// 多数据库迁移支持
            //builder.Services.AddDbContext<MigrationDbContext>(options =>
            //    options.UseSqlServer(builder.Configuration.GetConnectionString("MigrationDb")));
            // 初始化租户数据库
            //using (var scope = app.Services.CreateScope())
            //{
            //    var services = scope.ServiceProvider;
            //    var tenantResolver = services.GetRequiredService<ITenantResolver>();
            //    var tenants = builder.Configuration.GetSection("Tenants").GetChildren();

            //    foreach (var tenantSection in tenants)
            //    {
            //        var tenant = await tenantResolver.ResolveTenant(tenantSection.Key);
            //        await InitializeTenantDatabase(tenant, services);
            //    }
            //}

            //app.UseMiddleware<TenantMiddleware>();
            //async Task InitializeTenantDatabase(TenantInfo tenant, IServiceProvider services)
            //{
            //    var factory = new TenantDbContextFactory(tenant, services.GetRequiredService<IConfiguration>());
            //    using var context = factory.CreateDbContext();

            //    if (await context.Database.CanConnectAsync())
            //    {
            //        await context.Database.MigrateAsync();
            //    }
            //    else
            //    {
            //        await context.Database.EnsureCreatedAsync();
            //        await SeedInitialData(context);
            //    }
            //}
            //async Task SeedInitialData(AppDbContext context)
            //{
            //    if (!await context.Products.AnyAsync())
            //    {
            //        context.Products.Add(new Product
            //        {
            //            Name = "初始产品",
            //            Price = 9.99m,
            //            TenantId = context.TenantId
            //        });
            //        await context.SaveChangesAsync();
            //    }
            //}

            #endregion
            services.AddSingleton(typeof(IDataFilter<>), typeof(DataFilter<>));
            return services;
        }
        #endregion

        #region 开启全局缓冲
        public static void AddSSPivotGlobalBuffer(this IApplicationBuilder app)
        {
            app.Use(async (context, next) =>
            {
                context.Request.EnableBuffering();
                await next();
            });
        }
        #endregion

        #region 加载 
        public static void AddSSPivotModule(this WebApplicationBuilder builder)
        {
            // 使用 Autofac 替换默认 DI 容器
            builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
                .ConfigureContainer<ContainerBuilder>(containerBuilder =>
                {
                    containerBuilder.RegisterModule(new SSPivotAspNetCoreModule());
                });
        }
        #endregion

        #region orm
        public static void AddSSPivotData(this IServiceCollection services,DbConfig config)
        {
            
            // 注册负载均衡和动态DbContext
            services.AddSingleton<IDbLoadBalancer, DbLoadBalancer>();
            services.AddScoped<IDbContextFactory, DbContextFactory>();

            // 注册CAP分布式事务
            //services.AddCap(x =>
            //{
            //    x.UseSqlServer(opt => opt.ConnectionString = config.MasterDb);
            //    //x.UseRabbitMQ(conf =>
            //    //{
            //    //    conf.HostName = builder.Configuration["RabbitMQ:HostName"];
            //    //    conf.UserName = builder.Configuration["RabbitMQ:UserName"];
            //    //    conf.Password = builder.Configuration["RabbitMQ:Password"];
            //    //});
            //    x.FailedRetryCount = 5;
            //});

            // 注册依赖
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));  
            
            // 配置数据库选项
            //builder.Services.Configure<DatabaseOptions>(builder.Configuration.GetSection("Database"));
            // 原生DI配置
            //builder.Services.AddHttpContextAccessor();
            //builder.Services.AddDbContext<TenantDbContext>(options =>
            //    options.UseSqlServer(builder.Configuration.GetConnectionString("TenantDb")));
            //builder.Services.AddScoped<ITenantStore, TenantStore>();
            //builder.Services.AddScoped<TenantResolver>();
            //builder.Services.AddScoped<IDbContextFactory<AppDbContext>>(provider =>
            //    new CustomDbContextFactory(provider));
            //builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();


            // Autofac配置 
            //builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
            //    .ConfigureContainer<ContainerBuilder>(builder =>
            //    {
            //        builder.RegisterType<TenantProvider>().As<ITenantProvider>();
            //        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
            //        builder.RegisterType<ProductService>().As<IProductService>();
            //    });
            // Autofac配置
            //builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
            //    .ConfigureContainer<ContainerBuilder>(builder =>
            //    {
            //        builder.RegisterType<TenantStore>().As<ITenantStore>();
            //        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
            //        builder.RegisterType<ProductService>().As<IProductService>();
            //    });

            //appsetting 配置
            //"ConnectionStrings": {
            //    "TenantDb": "Server=.;Database=TenantManagement;Trusted_Connection=True;"
            // },            


            //            "MultiTenancy": {
            //                "Enabled": true
            //  },
            //  "Tenants": [
            //    {
            //                "Id": "tenant1",
            //      "Name": "Tenant 1",
            //      "DatabaseType": "SqlServer",
            //      "ConnectionString": "Server=.;Database=Tenant1Db;Trusted_Connection=True;"
            //    },
            //    {
            //                "Id": "tenant2",
            //      "Name": "Tenant 2",
            //      "DatabaseType": "MySql",
            //      "ConnectionString": "Server=localhost;Database=Tenant2Db;User=root;Password=123456;"
            //    }
            //  ]
            //}

            //        "Database": {
            //            "DefaultDatabaseType": "SqlServer",
            //"Connections": {
            //                "SqlServer": {
            //                    "WriteConnectionString": "Server=.;Database=DemoDb;Trusted_Connection=True;",
            //    "ReadConnectionStrings": [
            //      "Server=read1;Database=DemoDb;Trusted_Connection=True;",
            //      "Server=read2;Database=DemoDb;Trusted_Connection=True;"
            //    ]
            //                },
            //  "MySql": {
            //                    "WriteConnectionString": "Server=localhost;Database=DemoDb;User=root;Password=123456;",
            //    "ReadConnectionStrings": [
            //      "Server=read1;Database=DemoDb;User=root;Password=123456;"
            //    ]
            //  },
            //  "Sqlite": {
            //                    "WriteConnectionString": "Data Source=Demo.db",
            //    "ReadConnectionStrings": []
            //  }
            //            }
            //        }
            //   }

        }
    #endregion
}

}
